Classic 2D Snake game created in C++ with SFML library to help in visualization of the application. The main goal was to implement a snake as a custom Singly Linked List which helped me to understand and learn more about hits structure.
The core application structure consists of Application class in which the game loop has been implemented and all other lower level class are being updated. It is also responsible for initialization of the core classes that include GameWorld and MenuScreen classes.
SFML library is used to get an easy access to Open GL API as well as it's own event system and other vital elements.
Game World class stores all the game objects (in this case, a snake and it's body parts) and is responsible for calling update and render functions for all of them.
Menu Screen is a simple UI class that contains various UI elements such as menu screen and score value.
In my game, Snake is a simple object that consists of many body parts. Snake's head is a first element that defines the current position of the player. In order to build the whole body, we can just connect all the body parts to the head, or connect just one and then connect the second body part to the first one, third body part connect to the second one etc. This basically gives us a definition of Singly Linked List.
We can imagine that each body part is just a node. A node with a pointer to its predecessor and a certain type of data. In this case, data is represented by a Snake Body Element class. I decided to created my own Singly Linked List which is a class template. This means it can receive any type upon creation. This will define the type of data that will be stored in Nodes. The image below shows an initialization of a snake body (Single Linked List class) with SnakeBodyElem class a template parameter.
Snake updates it's position every frame and reacts to the user's input, changing its movement direction.
The rules of the game are simple: hit a food object in order to eat it, increase the Snake's length and get score. The more food has bed eaten, the higher score will be but the game will become harder as the longer snake is more fragile and the chance of mistake is higher. If player will hit the wall, the game is over. There is no score limit so player can play until the game is over or he can exit the game via in-game menu system.
New Snake body element will be added for each food eaten by the player. Because the snake is a simple linked list structure, adding new elements, connected to each other is quite easy. Once the food is eaten, the only thing we need to find is the last element (tail). We want to add to it another element that ultimately will become a new tail element.
The AddBodyElem function find a tails element (the last element in the structure) and caches locally it's position. The position will be used to instantiate a new SnakeBodyElem object. Then, the element will be added at the end of the Singly Linked List, becoming a new tail element.
I decided to make my own Single Linked List class in order learn how this structure works and how it might be implemented. I didn't want to unnecessary increase coupling in my game and make a Singly Linked list with already defined data type to store. I wanted to make in universal and flexible, so that it can be used in any other project. This was the main reason behind my decision to make it a class template and let the user define the data to store upon list initialization.
The list itself consists of many nodes. Each node is represented by a node structure containing a pointer to the preceding node in a structure.
As a class template, my list can take any type and use it as data in node. We can access certain elements and modify the structure by calling functions provided by the list class.
New elements can be pushed either at the front or at the end of the list. Same goes with removing nodes, only first and last element can be removed. In order to extend the list functionality I would add a ability to add/remove any element from the structure but it wasn't necessary for the Snake game since only the last element needs to be modified (we add a new element at the end of the structure after the Snake ate a food).
The PushBack function is the main function used in the game to increase the size of the Snake.
PushFront might be also used, there is no difference as the final effect will be the same, the Snake will get bigger.
In order to push an element to the back of the structure, we start with a already instantiated structure.
Knowing the head and the tail elements, we can push the new element either to the front or the end of the list.
This process will make a new element the current list's tail and the previous tale will become a normal element.
User Interface in Snake is very simple. There are only two buttons in the main menu to start or exit the game. I implemented it using simple shapes and text provided by SFML library.